re - regex python package

# 1
p = re.compile(r'([0-9]|10)([SDT])([\*\#]?)')
p.findall('1S2D*3T')

# 2
re.findall(r'([0-9]|10)([SDT])([\*\#]?)', '1S2D*3T')

자주 쓰는 re 메서드들

re.group

https://docs.python.org/3/library/re.html#re.Match.group

regex에서 그룹을 사용하면 인덱싱을 돌릴 수 있다.

If the regular expression uses the (?P<name>...) syntax, the groupN arguments may also be strings identifying groups by their group name.

re.sub

re.sub - doc
미국식, 영국식 날짜로 표기하시오

입력: '2023/05/16'
출력1: '05/16/2023' 미국식 날짜 표기 월 -> 일 -> 년 순임...
출력2: '16/05/0223' 영국식 날짜 표기 일 -> 월 -> 년 순임...

regex 그룹에 변수명을 붙일 수 있다...'

(?P<VARNAME>PATTERN) 으로 그룹을 선언하면 sub을 사용할 때 해당 그룹을 맞춰갈 수 있다.

import re

# regex 그룹에 변수명을 붙일 수 있다... 바로 '?P<var-name>'
pattern = r'(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})'
r = re.compile(pattern)
strings = '''2023/05/16
1997/09/26
1968/10/06
1973/05/20
1999/06/19'''
print(r.findall(strings))

print('\n미국식 날짜표기\n')
for s in strings.split('\n'):
    print(r.sub(r'\g<month>/\g<day>/\g<year>', s)) 

print('\n영국식 날짜표기\n')
for s in strings.split('\n'):
    print(r.sub(r'\g<day>/\g<month>/\g<year>', s))


# 연습문제

- [숨어있는 숫자의 덧셈](https://school.programmers.co.kr/learn/courses/30/lessons/120851)

loop + `str.isdigit` 활용하여 풀기
```python
def solution(my_string):
    ret = 0
    for c in my_string:
        if c.isdigit():
            ret += int(c)
    return ret

list comprehension 활용하여 풀기

def solution(my_string):
 	return sum(int(c) for c in my_string if c.isdigit())

re.findall

369 게임

주어진 숫자 안에 있는 3, 6, 9의 숫자를 세시오.

import re
solution = lambda order: len(re.findall('[369]', str(order)))

solution(29423)

연습문제: 잘라서 배열로 저장하기

https://school.programmers.co.kr/learn/courses/30/lessons/120913

사실 슬라이싱 문법 사용하여 간단하게 풀어도 되지만 findall을 사용하여 풀어보자

# slicing 사용
solution = lambda my_str, n: [my_str[l:l + n] for l in range(0, len(my_str), n)]
solution('abc1Addfggg4556b', 6)
import re
# re.findall 사용
# python에서 {를 넣기 위해선 {{를 사용하여야 합니다
solution = lambda my_str, n: re.findall(f'.{{1,{n}}}', my_str)
solution('abc1Addfggg4556b', 6)

연습문제: 영어가 싫어요

https://school.programmers.co.kr/learn/courses/30/lessons/120894

import re

pair = {
    'one':   '1',
    'two':   '2',
    'three': '3',
    'four':  '4',
    'five':  '5',
    'six':   '6',
    'seven': '7',
    'eight': '8',
    'nine':  '9',
    'zero':  '0',
}

def solution(numbers):
    return int(
        ''.join(
            pair[i] for i in re.findall(
                r'(zero|one|two|three|four|five|six|seven|eight|nine)', numbers))
    )

solution('onetwothreefourfivesixseveneightnine')

연습문제: 암호문

https://pyalgo.co.kr/?page=2#

import re

def solution(string):
    sum_ = sum(int(x) for x in re.findall(r'[rev](10|[1-9])', string))
    sum_ = str(sum_)
    return f'{sum_[0]}월 {sum_[1]}일'

solution('a10b9r10ce33uab8wc918v2cv11v10')

re.split

정규표현 패턴으로 문자열을 분할한다. str.split과 같음

import re

s = '010 8752!4037'

re.split(r'[ !]', s)

연습문제: Markdown 문법을 Html 문법으로

Before:

# Hello world

After:

<h1>Hello world<h1>
import re

text = '''
# This is a heading

## This is a subheading

* This is an unordered list item
* This is another unordered list item

**This is bold text**

_This is italic text_

`This is code`
'''


def markdown_to_html(text):
    """
    마크다운 텍스트를 HTML 문서로 변환합니다.

    Args:
        text: 변환할 마크다운 텍스트.

    Returns:
        변환된 HTML 문서.
    """

    # 마크다운을 HTML로 변환하기 위한 정규식 패턴 목록입니다.
    substitution_pairs = [
        (r'^# (.*)', r'<h1>\1<h1>'),
        (r'^## (.*)', r'<h2>\1<h2>'),
        (r'^### (.*)', r'<h3>\1<h3>'),
        (r'^#### (.*)', r'<h4>\1<h4>'),
        (r'^\* (.*)', r'<ul><li>\1</li></ul>'),
        (r'^\- (.*)', r'<ol><li>\1</li></ol>'),
        # (r'**(.*)**', r'<strong>\1</strong>'),  # 문제가 있는듯
        (r'_(.*)_', r'<em>\1</em>'),
        (r'`(.*)`', r'<code>\1</code>'),
    ]

    # 정규식 패턴을 사용하여 마크다운을 HTML로 변환합니다.
    for pat, repl in substitution_pairs:
        text = re.sub(pat, repl, text)   

    return text


# HTML을 출력합니다.
print(markdown_to_html(text))

다른 사람들의 개쩌는 MD -> HTML 코드

# 바름님 코드
import re

def md_to_html(text):
    # 토글
    text = re.sub(r'(>+) (.*)', r'<blockquote>\1 \2</blockquote>', text)
    # 헤딩
    text = re.sub(r'### (.*)', r'<h3>\1</h3>', text)
    text = re.sub(r'## (.*)', r'<h2>\1</h2>', text)
    text = re.sub(r'# (.*)', r'<h1>\1</h1>', text)
    # 코드블럭
    if re.match('\t?```', text):
        text = re.sub(r'^\t?```.*', r'<pre><code>', text)
        text = re.sub(r'\t?```', i):
        temp += i
        if flag == 1:
            f2.write(md_to_html(temp))
            temp, flag = '', 0   
        flag = 1
        continue
    if flag == 1:
        temp += i
        continue
    # 순서있는 리스트 처리
    if re.match(r'[ \t]*\d+\.', i):
        temp += i
        flag = 2
        continue
    if flag == 2:
        f2.write(md_to_html(temp))
        temp = ''
    # 순서없는 리스트 처리
    if re.match(r'[ \t]*[\*-]+[ \t]+', i):
        temp += i
        flag = 3
        continue
    if flag == 3:
        f2.write(md_to_html(temp))
        temp = ''
    #특이사항없을시
    f2.write(md_to_html(i))

f1.close()
f2.close()

파이썬 모듈 markdown을 활용

0014.4 markdown - python package

{% endraw %}
, r'', text)
text = re.sub(r'\t?(.*)', r'

\1
', text)
# 볼드
text = re.sub(r'[*]{2}(.*)[*]{2}', r'\1', text)
# 이탤릭
text = re.sub(r'[*]{1}(.*)[*]{1}', r'\1', text)
# 취소선
text = re.sub(r'(.*)', r'\1', text)
# 이미지
text = re.sub(r'![(.)]((.))', r'

', text)
# 링크
text = re.sub(r'[(.)]((.))', r'
\1
', text)
# 순서 없는 리스트
if re.match(r'[ \t][*-]+[ \t]+', text):
text = re.sub(r'[1]
[*-]+[ \t]+(.+)', r'\n
  • \1
  • ', text)
    text = re.sub(r'[ \t][*-]+[ \t]+(.+)', r'
  • \1
  • ', text)
    text += ''
    # 순서 있는 리스트
    if re.match(r'[ \t]
    \d+.', text):
    text = re.sub(r'[2]\d+.[ \t]+(.+)', r'
      \n
    1. \1
    2. ', text)
      text = re.sub(r'[ \t]\d+.[ \t]+(.+)', r'
    3. \1
    4. ', text)
      text += '
    '
    return text

    name = 'markdown'

    f1 = open(f'{name}.md', 'r' ,encoding='UTF8')
    f2 = open(f'{name}.html', 'w' ,encoding='UTF8')
    text = f1.readlines()
    temp = ''
    flag = 0
    for i in text:
    # 여러줄짜리 코드블럭 처리
    if re.match('\t?```', i):
    temp += i
    if flag == 1:
    f2.write(md_to_html(temp))
    temp, flag = '', 0
    flag = 1
    continue
    if flag == 1:
    temp += i
    continue
    # 순서있는 리스트 처리
    if re.match(r'[ \t]\d+.', i):
    temp += i
    flag = 2
    continue
    if flag == 2:
    f2.write(md_to_html(temp))
    temp = ''
    # 순서없는 리스트 처리
    if re.match(r'[ \t]
    [*-]+[ \t]+', i):
    temp += i
    flag = 3
    continue
    if flag == 3:
    f2.write(md_to_html(temp))
    temp = ''
    #특이사항없을시
    f2.write(md_to_html(i))

    f1.close()
    f2.close()

    
    ## 파이썬 모듈 `markdown`을 활용
    
    0014.4 markdown - python package
    
    
    {% endraw %}
    

    1. \t ↩︎

    2. \t ↩︎